<?php

class User extends ActiveRecordBase
{
	private $_salt;

	public $initialPassword;
	public $password1;
	public $password2;

	public $usergroup_ids;

	public $total_purchased;
	public $total_deposited;
	public $balance;

	public $no_update_to_ID = false;
	
	public $usermeta = array();

	public function __construct() {
		$this->_salt = Yii::app()->params['salt'];
	}

    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

	public function validatePassword($password)
    {
        return $this->hashPassword($password, $this->_salt)===$this->password;
    }

    public function hashPassword($password, $salt = false)
    {
		return md5($password); // ignore salt for now
//		if ( $salt === false ) $salt = $this->_salt;
//        return md5($salt.$password);
    }

    public function tableName()
    {
        return '{{users}}';
    }

	public function relations() {
		return array(
			'avatar' => array(self::HAS_ONE, 'ImageLink', 'object_id', 'on' => "avatar.object_type='user' AND avatar.type='M'"),
			
			'usergroups' => array(self::MANY_MANY, 'Usergroup', '{{usergroup_links}}(user_id, usergroup_id)'),
			  
			'userMeta' => array(self::HAS_MANY, 'UserMeta', 'user_id'),
			
			'friend' => array(self::MANY_MANY, 'User', '{{friends}}(user_id, friend_id)'),
			'friendCount' => array(self::STAT, 'User', '{{friends}}(user_id, friend_id)'),

			'friendRequest' => array(self::MANY_MANY, 'User', '{{friend_requests}}(to_user_id, from_user_id)'),
			'friendRequestCount' => array(self::STAT, 'User', '{{friend_requests}}(to_user_id, from_user_id)'),
			
			'stat' => array(self::HAS_ONE, 'UserStat', 'user_id'),

			'message' => array(self::HAS_MANY, 'UserMessage', array('user_id' => 'to_user_id')),
			'messageCount' => array(self::STAT, 'UserMessage', 'to_user_id', 'condition' => 't.status="A"'),
		);
	}

	public function rules()
	{
		return array(
			array('user_login, status, user_type, email', 'required'),
			array('password1, password2', 'required', 'on' => 'add'),
			array('email', 'email'),
			array('password2', 'compare', 'compareAttribute' => 'password1'),
			array('password1, password2, name, phone', 'safe'),
			array('password', 'safe'),
			array('people_id, commission', 'safe'),
			array('gender', 'in', 'range' => array('M', 'F', 'O'), 'allowEmpty' => true),
			array('privacy', 'in', 'range' => array('public', 'friend', 'private'), 'allowEmpty' => true), 
		);
	}

	public function beforeSave()
    {
        // in this case, we will use the old hashed password.
        if( trim($this->password1) == '' && trim($this->password2) == '' && !empty($this->initialPassword) )
            $this->password = $this->password1 = $this->password2 = $this->initialPassword;

		if( parent::beforeSave() ) {
			if( $this->isNewRecord ) {
				$this->timestamp = time();
			}
			return true;
		} else {
			return false;
		}
    }

	public function afterSave()
	{
		if ( !$this->no_update_to_ID )
			$this->updateUser();
		
		// attach image pairs
		Image::attachImagePair('user_main', 'user', $this->user_id);
	}

    public function afterFind()
    {
        //reset the password to null because we don't want the hash to be shown.
        $this->initialPassword = $this->password;
        $this->password1 = str_repeat(' ', 10);
        $this->password2 = str_repeat(' ', 10);

        parent::afterFind();
    }

	public function attributeLabels()
	{
		return array(
			'email' => t('Email'),
			'password' => t('Password'),
			'password1' => t('Password'),
			'password2' => t('Confirm Password'),
			'status' => t('Status'),
			'user_type' => t('User Type'),
			'name' => 'Name',
			'phone' => t('Phone'),
		);
	}

	public function createUser($user_data = array()) {
		$this->isNewRecord = true;
		if ( !empty($user_data) ) {
			$this->attributes = $user_data;
		}
		$this->password = $this->hashPassword($this->password);

		$user = User::model();
		$user->attributes = $user_data;
		$user->isNewRecord = true;

		$user->save(false);
 
		$this->seo_name = sprintf('%s.%s', $this->user_id, SiteHelper::generateSeoName(substr($this->user_login, 0, strpos($this->user_login, '@'))));
		if ( !$this->save(false) ) {
			return array('code' => '13');
		}

		return true;
	}

	public function updateUser() {
	}

	public function getUser($id) {
		$model = $this->with(array(
				'avatar.image',
			))->findByPk($id);

		$usergroups = app()->db->createCommand()
					->select('usergroup_id')
					->from('{{usergroup_links}}')
					->where('user_id=:user_id', array(':user_id' => $id))
					->queryColumn();

		$model->usergroup_ids = $usergroups; 
		$model->balance = 0;
		return $model;
	}

	public static function getUserBalance($user_id) {
		 
		return 0;
	}

	public function setUsergroups($usergroups) {
		if ( !is_array($usergroups) ) $usergroups = array($usergroups);

		if ( !empty($usergroups) ) {
			app()->db->createCommand("DELETE FROM {{usergroup_links}} WHERE user_id=:user_id")->execute(array(':user_id' => $this->user_id));
			foreach ($usergroups as $usergroup_id) {
				$command = app()->db->createCommand("REPLACE INTO {{usergroup_links}}(usergroup_id, user_id) VALUES (:usergroup_id, :user_id)");
				$command->execute(array(
					':usergroup_id' => $usergroup_id,
					':user_id' => $this->user_id,
				));
			}
		}
	}  
	public static function getStats() {
		$command = app()->db->createCommand()->select('user_type, COUNT(*) as total')->from('{{users}}')
				->where("user_type IN ('A', 'C')")
				->group('user_type');

		$_results = $command->queryAll();
		$results = array();
		foreach ((array)$_results as $r) {
			$results[$r['user_type']] = $r['total'];
		}

		$command = app()->db->createCommand()->select('COUNT(*) as total')->from('{{users}}')->where("user_type IN ('A', 'C')");
		$total = $command->queryRow();

		return array($results, $total);
	}

	public static function getAuthConfig() {
		$config = array(
			'base_url' => param('frontUrl').'user/authEndPoint',
			'providers' => array(
				"Google" => array (
					"enabled" => true,
					"keys"    => array ( "id" => "41271701926.apps.googleusercontent.com", "secret" => "LgNvI0Hqjl6_Zp3z_pxdok2M" )
				),
				"Facebook" => array (
					"enabled" => true,
					"keys"    => array ( "id" => "485521614856703", "secret" => "753af2f99cd80ecf924b5ea1da63dc6b" ),
					'scope'   => 'email, user_location',
				),
				"Yahoo" => array (
					"enabled" => true,
					"keys"    => array ( //"id" => " 6wHnhK32",
						'key' => 'dj0yJmk9WDRrV1pJRlRScHM5JmQ9WVdrOU5uZElibWhMTXpJbWNHbzlNVFl4TkRnMk1EazJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD00Mg--', "secret" => "d9a50601cacd7d73bddd80400fdf94aa6be54572" )
				),
			),
			"debug_mode" => false,
			"debug_file" => Yii::getPathOfAlias('hybridauth').'/Hybrid/storages/debug.txt',
		);

		return $config;
	}
 

	public static function getUserTypes() {
		$user_types = array(
			'C' => t('Member'),
			'A' => t('Administrator'),
			//'B' => t('CP'),
			//'F' => t('CTV'),
		);

		if ( !user()->checkPerm('ctv_manage') ) {
			unset($user_types['F']);
		} elseif ( !user()->checkPerm('user_manage') ) {
			unset($user_types['A']);
			unset($user_types['C']);
			unset($user_types['B']);
		}

		return $user_types;
	}
	
	public static function generatePassword($length = 12, $special_chars = true, $extra_special_chars = false) {
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
		if ( $special_chars )
			$chars .= '!@#$%^&*()';
		if ( $extra_special_chars )
			$chars .= '-_ []{}<>~`+=,.;:/?|';

		$password = '';
		for ( $i = 0; $i < $length; $i++ ) {
			$password .= substr($chars, rand(0, strlen($chars) - 1), 1);
		}

		// random_password filter was previously in random_password function which was deprecated
		return $password;
	}
	
	public function getUserMeta($meta_key = '', $force_reload = false) {
		if ( empty($this->usermeta) || $force_reload ) {

			$meta = $this->userMeta;
			if ( !empty($meta) ) {
				$usermeta = array();
				foreach ($meta as $m) {
					$usermeta[$m->meta_key] = $m->meta_value;
				}

				$this->usermeta = $usermeta;
			}
		}
		
		return $meta_key ? (isset($this->usermeta[$meta_key]) ? $this->usermeta[$meta_key] : null) : $this->usermeta;
	}
	
	public function saveUserMeta() {
		if ( !empty($this->usermeta) ) {
			foreach ($this->usermeta as $k => $v) {
				$this->updateUserMeta($k, $v);
			}
		}
	}
	
	public function updateUserMeta($meta_key, $meta_value) {
		$model = UserMeta::model()->findByAttributes(array(
			'user_id' => $this->primaryKey,
			'meta_key' => $meta_key,
		));
		
		if ( empty($model) ) $model = new UserMeta;
		
		$model->user_id = $this->primaryKey;
		$model->meta_key = $meta_key;
		$model->meta_value = $meta_value;
		return $model->save();
	}
	
	public function deleteUserMeta($meta_key) {
		$model = UserMeta::model()->findByAttributes(array(
			'user_id' => $this->primaryKey,
			'meta_key' => $meta_key,
		));
		
		if ( !empty($model) ) return $model->delete();
		
		return false;
	}

	public function countNotification() {
		return (int) $this->friendRequestCount + (int) $this->messageCount;
	}
	
	public function getProfileUrl() {
		return app()->urlManager->createUrl('/user/view/', array('name' => $this->seo_name));
	}

	public function getFriendUrl() {
		return app()->urlManager->createUrl('/user/friend/', array('name' => $this->seo_name));
	}

	public function getAcceptFriendUrl() {
		return app()->urlManager->createUrl('/user/acceptFriend/', array('name' => $this->seo_name));
	}

	public function getRejectFriendUrl() {
		return app()->urlManager->createUrl('/user/rejectFriend/', array('name' => $this->seo_name));
	}
	  
	
	public function isFriend($user_id) {
		return Friend::isFriend($this->user_id, $user_id);
	}
	
	public function requestedFriend($user_id) {
		return FriendRequest::sentRequest($user_id, $this->user_id);
	}
	
	public static function applyFilters($criteria, $filters) {
		if ( !empty($filters['name']) ) {
			$criteria->addSearchCondition('t.name', $filters['name']);
		}
		
		if ( !empty($filters['email']) ) {
			$criteria->addSearchCondition('t.email', $filters['email']);
		}

		if ( !empty($filters['period']) || !empty($filters['time_from']) || !empty($filters['time_to']) ) {
			list($time_from, $time_to) = createPeriods($filters);

			$criteria->addCondition('t.timestamp>=:time_from');
			$criteria->addCondition('t.timestamp<=:time_to');
			$criteria->params[':time_from'] = $time_from;
			$criteria->params[':time_to'] = $time_to;

			$filters['time_from'] = formatDate($time_from);
			$filters['time_to'] = formatDate($time_to);
		}

		if ( !empty($filters['status']) ) {
			$criteria->addCondition('t.status=:status');
				$criteria->params[':status'] = $filters['status'];
		}
	}

	public static function getFriends($user_id) {
		$user = User::model()->with('friend')->findByPk($user_id);

		if ( !empty($user->friend) )
			return $user->friend;

		return array();
	}
	
	public function advanceSearchWithUser($query, $sortby = 'timestamp', $sortdir = 'desc', $record_per_page = DEFAULT_PAGE_SIZE, $page = 0, $user_id = 0, $status = 'A')
	{
		//escape
		$query = addcslashes($query, '%_');
		$from = ($page < 1) ? 0 : ($page - 1) * $record_per_page;
		//Build SQL for User and Product Search
		$main_sql = "
						SELECT 
					    u.user_id as id, 1 as is_user, u.timestamp as timestamp, u.email as name, 0 as price
					    FROM {{users}} u 
					    WHERE  (u.email like :query or u.name like :query)
					    AND u.Status = '$status' 
					";
		//Total SQL
		$total_sql = "SELECT COUNT(*) as total FROM ($main_sql) as total_tbl";
		//Top Limited SQL
		$sql = "
					SELECT * FROM 
					(
					    $main_sql
						
					) result
					order by $sortby $sortdir
					LIMIT $from, $record_per_page
 				";
		//Result
		$total = app()->db->createCommand($total_sql)->queryAll(true, array(':query'=>"%".strtolower($query)."%"));
		return array(
			'total' => $total[0]{'total'},
			'data' => app()->db->createCommand($sql)->queryAll(true, array(':query'=>"%".strtolower($query)."%"))
		);
	}
}
?>